//
// Created by ole on 24-8-21.
//

#ifndef BASEPLUGIN_H
#define BASEPLUGIN_H
#include <memory>
#include <mutex>
#include <sstream>
#include "IPlugin.h"
#include "../ipc/IPCManager.h"

class Message;
class MessageReceiver;
class Topic;

class BasePlugin : public IPlugin {
public:
    BasePlugin(std::string name, std::string version);

    ~BasePlugin() override;

    void setIPCManager(const std::shared_ptr<IPCManager> &ipcManager);

    std::string getName() override;

    std::string getVersion() override;

    bool isStarted() override;

    bool start() override;

    bool stop() override;

    void notifyStateChanged(const std::string &state);

    void subscribe(const std::shared_ptr<Topic> &topic, const std::shared_ptr<MessageReceiver> &receiver) const;

    void unsubscribe(const std::shared_ptr<Topic> &topic, const std::shared_ptr<MessageReceiver> &receiver) const;

    void publishMessage(const std::shared_ptr<Message> &msg) const;

    template<typename T>
    T *instance() {
        return dynamic_cast<T *>(sInstance);
    }

    virtual bool onStart() = 0;

    virtual bool onStop() = 0;

    std::string toString() override {
        std::lock_guard<std::mutex> lock(memberMutex);
        std::ostringstream ss;
        ss << TAG << "{";
        ss << "name='" << name << "', ";
        ss << "version='" << version << "', ";
        ss << "}";
        return ss.str();
    }

    std::string TAG;

private:
    std::mutex memberMutex;
    std::string name;
    std::string version;
    std::shared_ptr<IPCManager> ipcManager;

    bool started;
    BasePlugin *sInstance;
};

#endif //BASEPLUGIN_H
